// 云函数：智能组卷
const cloud = require('wx-server-sdk');

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
});

const db = cloud.database();
const questionCollection = db.collection('questions');
const _ = db.command;

/**
 * 智能组卷云函数
 * 
 * 参数：
 * - subject: 学科（必填）
 * - difficulty: 整体难度 1-5（必填）
 * - totalScore: 总分（必填）
 * - questionTypes: 题型配置 [{ type, count, scorePerQuestion }]（必填）
 * - knowledgePoints: 知识点配置 [{ name, weight }]（可选）
 */
exports.main = async (event, context) => {
  const { subject, difficulty, totalScore, questionTypes, knowledgePoints = [] } = event;
  const wxContext = cloud.getWXContext();
  const userId = wxContext.OPENID;
  
  try {
    // 参数校验
    if (!subject) {
      return {
        success: false,
        message: '请指定学科'
      };
    }
    
    if (!difficulty || difficulty < 1 || difficulty > 5) {
      return {
        success: false,
        message: '难度值必须在1-5之间'
      };
    }
    
    if (!totalScore || totalScore <= 0) {
      return {
        success: false,
        message: '总分必须大于0'
      };
    }
    
    if (!questionTypes || !Array.isArray(questionTypes) || questionTypes.length === 0) {
      return {
        success: false,
        message: '请指定题型配置'
      };
    }
    
    // 1. 计算各题型实际需要的题目数量
    let totalConfiguredScore = 0;
    
    for (const config of questionTypes) {
      totalConfiguredScore += config.count * config.scorePerQuestion;
    }
    
    if (totalConfiguredScore !== totalScore) {
      return {
        success: false,
        message: `题型配置总分(${totalConfiguredScore})与试卷总分(${totalScore})不一致`
      };
    }
    
    // 2. 根据难度和知识点权重构建查询条件
    const difficultyRange = getDifficultyRange(difficulty);
    
    // 3. 查询每种题型的题目
    const selectedQuestions = [];
    let currentTotalScore = 0;
    
    for (const config of questionTypes) {
      const { type, count, scorePerQuestion } = config;
      
      // 构建查询条件
      const query = {
        subject: subject,
        type: type,
        difficulty: _.gte(difficultyRange.min).lte(difficultyRange.max)
      };
      
      // 添加知识点筛选
      if (knowledgePoints && knowledgePoints.length > 0) {
        const knowledgeNames = knowledgePoints.map(k => k.name);
        query.knowledge = _.elemMatch(_.in(knowledgeNames));
      }
      
      // 查询符合条件的题目
      const questions = await questionCollection
        .where(query)
        .get();
      
      // 如果找不到足够的题目
      if (questions.data.length < count) {
        return {
          success: false,
          message: `${getQuestionTypeName(type)}题型题目库中数量不足，需要${count}题，实际只有${questions.data.length}题`
        };
      }
      
      // 根据知识点权重和难度进行排序和选择
      const sortedQuestions = sortQuestionsByKnowledgeAndDifficulty(
        questions.data,
        knowledgePoints,
        difficulty
      );
      
      // 选择需要的题目数量
      const selected = sortedQuestions.slice(0, count).map(question => {
        return {
          questionId: question._id,
          type: question.type,
          score: scorePerQuestion,
          subject: question.subject,
          knowledge: question.knowledge,
          difficulty: question.difficulty
        };
      });
      
      selectedQuestions.push(...selected);
      currentTotalScore += selected.length * scorePerQuestion;
    }
    
    // 4. 创建试卷
    const paper = {
      title: `${subject}智能组卷(${totalScore}分)`,
      subject: subject,
      description: `难度${difficulty}，总分${totalScore}分的智能组卷`,
      duration: calculateExamDuration(totalScore),
      totalScore: totalScore,
      questions: selectedQuestions,
      creator: userId,
      status: 'draft',
      createTime: db.serverDate(),
      updateTime: db.serverDate()
    };
    
    // 5. 保存到数据库
    const result = await db.collection('papers').add({
      data: paper
    });
    
    return {
      success: true,
      paperId: result._id,
      paper: {
        ...paper,
        _id: result._id
      },
      message: '智能组卷成功'
    };
  } catch (error) {
    console.error('智能组卷失败:', error);
    return {
      success: false,
      message: '智能组卷失败: ' + error.message
    };
  }
};

/**
 * 根据难度值获取难度范围
 * @param {Number} difficulty 难度值(1-5)
 * @returns {Object} 难度范围
 */
function getDifficultyRange(difficulty) {
  let min, max;
  
  switch (difficulty) {
    case 1: // 简单
      min = 1;
      max = 2;
      break;
    case 2: // 较简单
      min = 1;
      max = 3;
      break;
    case 3: // 中等
      min = 2;
      max = 4;
      break;
    case 4: // 较难
      min = 3;
      max = 5;
      break;
    case 5: // 困难
      min = 4;
      max = 5;
      break;
    default:
      min = 1;
      max = 5;
  }
  
  return { min, max };
}

/**
 * 根据知识点权重和难度对题目进行排序
 * @param {Array} questions 题目列表
 * @param {Array} knowledgePoints 知识点权重配置
 * @param {Number} targetDifficulty 目标难度
 * @returns {Array} 排序后的题目
 */
function sortQuestionsByKnowledgeAndDifficulty(questions, knowledgePoints, targetDifficulty) {
  // 创建知识点权重映射
  const knowledgeWeightMap = {};
  knowledgePoints.forEach(item => {
    knowledgeWeightMap[item.name] = item.weight || 1;
  });
  
  // 计算每个题目的适合度分数
  const scoredQuestions = questions.map(question => {
    let knowledgeScore = 0;
    
    // 计算知识点匹配分数
    if (question.knowledge && question.knowledge.length > 0) {
      for (const k of question.knowledge) {
        knowledgeScore += knowledgeWeightMap[k] || 0;
      }
      // 归一化知识点分数
      knowledgeScore = knowledgeScore / question.knowledge.length;
    }
    
    // 计算难度匹配分数 (满分10, 完全匹配得10分)
    const difficultyScore = 10 - Math.abs(question.difficulty - targetDifficulty) * 2;
    
    // 综合分数 (知识点权重60%, 难度权重40%)
    const totalScore = knowledgeScore * 0.6 + difficultyScore * 0.4;
    
    return {
      ...question,
      matchScore: totalScore
    };
  });
  
  // 根据综合分数降序排序
  return scoredQuestions.sort((a, b) => b.matchScore - a.matchScore);
}

/**
 * 根据总分计算考试时长（分钟）
 * @param {Number} totalScore 总分
 * @returns {Number} 考试时长(分钟)
 */
function calculateExamDuration(totalScore) {
  // 根据总分计算推荐时长，每分约1分钟
  return Math.max(45, Math.min(180, Math.ceil(totalScore * 1.2)));
}

/**
 * 获取题型中文名称
 * @param {String} typeCode 题型代码
 * @returns {String} 题型中文名称
 */
function getQuestionTypeName(typeCode) {
  const typeMap = {
    'single_choice': '单选题',
    'multiple_choice': '多选题',
    'true_false': '判断题',
    'fill_blank': '填空题',
    'short_answer': '简答题'
  };
  
  return typeMap[typeCode] || typeCode;
} 